#pragma once

#include "nvds_constants.h"
#include "nvds_element.h"
#include "nvds_sourcebin.h"
#include <gst/gst.h>
#include <initializer_list>
#include <nvds_obj_encode.h>
#include <memory>
#include <utility>
#include <vector>

struct NVDSJpgEncParam {
    int  jpg_quality  = 30;
    bool scale_enable = false; // 是否开启图片缩放
    int  scale_width  = 1280;  // 图片缩放宽度
    int  scale_height = 720;   // 图片缩放高度
};

class NVDSPipeline
{
    typedef std::shared_ptr<NVDSSourcebin>                NVDSSourcebinPtr;
    typedef std::function<void(const DetectResultList &)> ResultCallback;

public:
    NVDSPipeline();
    ~NVDSPipeline();

public:
    void start(const std::string &conf_file);
    void stop();

    /**
     * @brief Set the Callback function
     *
     * @param cb
     */
    void setCallback(ResultCallback cb)
    {
        m_retCallback = cb;
    }

private:
    /**
     * @brief 配置文件读取
     *
     * @param filename
     * @return true
     * @return false
     */
    bool loadConfig(const std::string &filename);
    /**
     * @brief pipeline 初始化
     *
     * @param urls
     */
    void pipelineInit(const std::vector<std::string> &urls);

    /**
     * @brief pipeline 销毁
     *
     */
    void pipelineDestroy();

private:
    static gboolean          bus_call(GstBus *bus, GstMessage *msg, gpointer data);
    static GstPadProbeReturn pgie_src_pad_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
    static GstPadProbeReturn tailer_sink_pad_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);

private:
    std::vector<std::string>      m_videoUrls;
    GstElement                   *m_pipeline;
    GstElement                   *m_streammux;
    bool                          m_useDisplay;  // 是否开启显示功能
    int                           m_inputWidth;  // 检测图像宽度
    int                           m_inputHeight; // 检测图像高度
    bool                          m_useJpgenc;   // 是否启用 nvds_jpg_enc
    NVDSJpgEncParam               m_jpgencParam; // jpgenc 参数信息
    NvDsObjEncCtxHandle           m_objCtxHandle;
    GMainLoop                    *m_gstLoop;
    guint                         m_busWatchId;
    std::vector<NVDSSourcebinPtr> m_sourcebins;
    ResultCallback                m_retCallback;
    NvDsFrameLatencyInfo         *m_latencyInfo;
    GMutex                        m_latencyLock;
};